import React, { Suspense } from "react";
import { createBrowserRouter, RouteObject } from "react-router-dom";
import IndexPage from "./IndexPage";

const elements = import.meta.glob("@/page/**/*.tsx", { eager: false }) as Record<string, () => Promise<{ default: React.ComponentType<any> }>>;
const configs = import.meta.glob("@/page/**/config.ts", { eager: true, import: "default" }) as Record<string, RouteConfig | undefined>;
/**
 * 一级路径匹配正则
 */
const firstPathRegExp = new RegExp("^\\/[^/]*$");
/**
 * 路由配置类型
 */
export type RouteConfig = {
  /**
   * 是否为索引路由
   */
  index: boolean;
}

/**
 * 自定义路由类型
 */
export type RouteDefinition = {
  /**
   * 路由路径
   */
  path: string;
  /**
   * 路由配置信息
   */
  config?: RouteConfig,
  // element: React.ReactElement
  /**
   * 路由组件key
   */
  elementKey: string
  /**
   * 子路由
   */
  children?: RouteDefinition[];
};


const parseRouterObject = (): RouteObject[] => {
  const mainRoute: RouteDefinition[] = []
  const subRoute: RouteDefinition[] = []
  // console.log("config.ts", configs)
  Object.keys(elements).forEach(key => {
    const configKey = key.replaceAll("index.tsx", "config.ts");
    const rk = key.replaceAll("/src/page", "").replaceAll("/index.tsx", "");
    const rd: RouteDefinition = {
      path: rk,
      config: configs[configKey],
      // element: lazyComponent(key),
      elementKey: key
    }
    if (firstPathRegExp.test(rk)) {
      mainRoute.push(rd)
    } else {
      subRoute.push(rd);
    }
  });
  mainRoute.forEach(route => {
    const children = findRouteChildren(route, subRoute);
    route.children = children;
  })
  console.info("构建路由信息: ", mainRoute);
  return transitionRouter(mainRoute);

}

/**
 * 获取路由对象
 * @returns 路由对象
 */
export function getRouter(): ReturnType<typeof createBrowserRouter> {
 return createBrowserRouter([
    {
      path: "/",
      element: <IndexPage/>,
      children: parseRouterObject()
    } 
  ]);
}
/**
 * 准换自定义路由信息为reactrouter路由对象
 * @param routers 文件路由列表
 * @returns reactrouter路由对象
 */
const transitionRouter = (routers: RouteDefinition[]): RouteObject[] => {
  return routers.map(r => {
    // 索引路由,不会出现子路由
    if (r.path.includes("index") || r.config?.index) {
      return {
        index: true,
        element: lazyComponent(r.elementKey)
      } as RouteObject
    }
    // 普通路由但是有子路由
    if (r.children && r.children.length > 0) {
      return {
        path: r.path,
        element: lazyComponent(r.elementKey),
        children: transitionRouter(r.children)
      } as RouteObject
    }
    // 普通的路由,可能出现子路由
    return {
      path: r.path,
      element: lazyComponent(r.elementKey),
      children: []
    } as RouteObject
  });
}

/**
 * 找到路由的直接子路由
 * @param currentRoute 当前路由
 * @param routes 全部的子路由
 */
const findRouteChildren = (currentRoute: RouteDefinition, routes: RouteDefinition[]) => {
  // 当前路径path必须是routes中的路径的直接父级路径
  const pathRegExp = new RegExp(`^${currentRoute.path}/[^/]*$`);
  const tempRes = routes.filter(route => pathRegExp.test(route.path))
  tempRes.forEach(route => {
    const children = findRouteChildren(route, routes);
    route.children = children;
  });
  return tempRes;
}

/**
 * 组件懒加载方法
 * @param key 动态导入组件的key
 * @returns 懒加载组件
 */
const lazyComponent = (key: keyof typeof elements): React.ReactElement => {
  const LazyComponent = React.lazy(elements[key]);
  return (
    <Suspense fallback={<div>loading</div>}>
      <LazyComponent />
    </Suspense>
  )
}